package com.augurit.common.util;

import java.util.HashMap;
import java.util.Map;

import org.springside.modules.orm.Page;


public class HqlUtils {

	public static final String RELATIONSHIP_AND = "and";
	public static final String RELATIONSHIP_OR = "or";
	
	public static final String HQL_SPACE_SEPARATOR = " ";	
	public static final String HQL_COMMA_SEPARATOR = ",";
	public static final String HQL_DOT_SEPARATOR = "\\.";
	
	
	/**
	 * 构造排序HQL语句
	 * @param page
	 * @param entityAlias
	 * @return
	 */
	public static String buildOrderBy(Page page, String entityAlias){
		String hql = "";
		if(page != null && page.getOrderBy() != null && page.getOrderBy().trim().length() > 0){
			hql = " order by " + entityAlias + "." + page.getOrderBy() + " " + (page.getOrder() != null ? page.getOrder() : "");
		}
		return hql;
	}
	
	/**
	 * 构造OR条件查询语句，如" (ps.id=1 or ps.id=2)"
	 * @param entityAlias Entity对象别名
	 * @param property Entity对象属性
	 * @param values Entity对象属性值
	 * @return
	 */
	public static String buildOrCondition(String entityAlias, String property, Long[] values){
		if(entityAlias != null && property != null && values != null && values.length > 0){
			String result = " (";
			
			for(int i=0; i<values.length; i++){
				result += entityAlias + "." + property + "=" + values[i];
				
				if(i < values.length - 1)
					result += " or ";
			}
			
			result += ")";
			
			return result;
		}else
			return "";
	}
	
	/**
	 * 构造OR条件查询语句，如" (ps.id=1 or ps.id=2)"
	 * @param entityAlias Entity对象别名
	 * @param property Entity对象属性
	 * @param values Entity对象属性值
	 * @return
	 */
	public static String buildOrCondition(String entityAlias, String property, String[] values){
		if(entityAlias != null && property != null && values != null && values.length > 0){
			String result = " (";
			
			for(int i=0; i<values.length; i++){
				result += entityAlias + "." + property + "='" + values[i] + "'";
				
				if(i < values.length - 1)
					result += " or ";
			}
			
			result += ")";
			
			return result;
		}else
			return "";
	}
	
	/**
	 * 构造全模糊查询语句，如" (ps.seq like '%test%' or ps.seq like '%test1%')"
	 * @param entityAlias Entity对象别名
	 * @param property Entity对象属性
	 * @param values Entity对象属性值
	 * @param relationship 逻辑与/逻辑或，即HqlUtils.RELATIONSHIP_AND 或 HqlUtils.RELATIONSHIP_OR
	 * @return
	 */
	public static String buildLikeCondition(String entityAlias, String property, String[] values, String relationship){
		if(entityAlias != null && property != null && values != null && values.length > 0){
			String result = " (";
			
			for(int i=0; i<values.length; i++){
				result += entityAlias + "." + property + " like '%" + values[i] + "%'";
				
				if(i < values.length - 1)
					result += " " + relationship + " ";
			}
			
			result += ")";
			
			return result;
		}else
			return "";
	}
	
	/**
	 * 构造and条件查询语句，如" (ps.id<>1 and ps.id<>2)"
	 * @param entityAlias Entity对象别名
	 * @param property Entity对象属性
	 * @param values Entity对象属性值
	 * @return
	 */
	public static String buildAndCondition(String entityAlias, String property, Long[] values){
		if(entityAlias != null && property != null && values != null && values.length > 0){
			String result = " (";
			
			for(int i=0; i<values.length; i++){
				result += entityAlias + "." + property + "<>" + values[i];
				
				if(i < values.length - 1)
					result += " and ";
			}
			
			result += ")";
			
			return result;
		}else
			return "";
	}
	
	
	/**
	 * 构造从别名到实体名的映射
	 * @param selectEntities
	 * @return
	 */
	public static Map<String, String> constructAliasToEntityMap(String selectEntities){
		String[] selectEntityArray = selectEntities.split(HQL_COMMA_SEPARATOR);
		
		Map<String, String> map = new HashMap<String, String>();
		for(int i = 0; i < selectEntityArray.length; i++){
			String[] entityAndAlias = selectEntityArray[i].split(HQL_SPACE_SEPARATOR);
			map.put(entityAndAlias[1], entityAndAlias[0]);
		}
		return map;
	}
	
	/**
	 * 通过分析查询实体字符串、查询属性字符，获取要查询表及对应的列，
	 * 比如实体字符串为：Notice notice,OaShouwen oaShouwen， 
	 * 属性字符串为:notice.content,notice.publishTime,oaShouwen.keyWord,oaShouwen.secrecyLimit
	 * 得到结果为
	 *    EntityPropertyPair[4] = {
	 *    	pair1, pair2, pair3, pair4
	 *    }
	 *    pair1 = {Notice, content}, pair2 = {notice, publishTime}
	 * @param selectEntities
	 * @param queryProperties
	 * @return
	 */
	public static TableColumnPair[] constructTableColumnPairs(String selectEntities, String queryProperties){
		
		Map<String, String> aliasToEntityMap = constructAliasToEntityMap(selectEntities);
		
		String[] queryPropertyArray = queryProperties.split(HQL_COMMA_SEPARATOR);
		
		TableColumnPair[] pairs = null;
		if(queryPropertyArray != null && queryPropertyArray.length > 0){
			pairs = new TableColumnPair[queryPropertyArray.length];
			int i = 0;
			for(String property:queryPropertyArray){
				String[] propteryStr = property.split(HQL_DOT_SEPARATOR);
				String alias = propteryStr[0];
				String propertyName = propteryStr[1];
				
				
				TableColumnPair pair = new TableColumnPair(aliasToEntityMap.get(alias), propertyName);
				pairs[i++] = pair;
			}
		}
		return pairs;
	}
	
	public static class TableColumnPair{
		private final String tableName;
		private final String columnName;
		
		
		public TableColumnPair(String tableName, String columnName){
			this.tableName = tableName;
			this.columnName = columnName;
		}

		public String getTableName() {
			return tableName;
		}


		public String getColumnName() {
			return columnName;
		}
		
		
	}
}
